package com.jwgf.smarowindingmachine_unity.ui;

import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.fragment.app.FragmentActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.alibaba.fastjson.JSON;
import com.jwgf.adapter.DensityUtils;
import com.jwgf.adapter.MultiItemTypeAdapter;
import com.jwgf.common.GlobalToast;
import com.jwgf.decoration.SpaceItemDecoration;
import com.jwgf.group.Group;
import com.jwgf.group.GroupMap;
import com.jwgf.itemviewdelegates.StatisticButtonAttr;
import com.jwgf.itemviewdelegates.StatisticButtonDelegate;
import com.jwgf.objectbox.GroupInfo;
import com.jwgf.objectbox.ShiftReport;
import com.jwgf.objectbox.SpindleParameter;
import com.jwgf.smarowindingmachine_unity.R;
import com.jwgf.smarowindingmachine_unity.logic.MachineParameterSharedPreference;
import com.jwgf.smarowindingmachine_unity.logic.Report;
import com.jwgf.smarowindingmachine_unity.logic.UnitUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.ObservableEmitter;
import io.reactivex.rxjava3.core.ObservableOnSubscribe;
import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.rxjava3.schedulers.Schedulers;
import lecho.lib.hellocharts.formatter.SimpleAxisValueFormatter;
import lecho.lib.hellocharts.gesture.ContainerScrollType;
import lecho.lib.hellocharts.listener.ComboLineColumnChartOnValueSelectListener;
import lecho.lib.hellocharts.model.Axis;
import lecho.lib.hellocharts.model.AxisValue;
import lecho.lib.hellocharts.model.Column;
import lecho.lib.hellocharts.model.ColumnChartData;
import lecho.lib.hellocharts.model.ComboLineColumnChartData;
import lecho.lib.hellocharts.model.Line;
import lecho.lib.hellocharts.model.LineChartData;
import lecho.lib.hellocharts.model.PointValue;
import lecho.lib.hellocharts.model.SubcolumnValue;
import lecho.lib.hellocharts.util.ChartUtils;
import lecho.lib.hellocharts.view.ComboLineColumnChartView;

public class ProductionSpindleView extends RelativeLayout {

    private TextView filterText;
    private ImageButton filterBtn;

    private TextView craftContent;

    private RecyclerView rv;
    private MultiItemTypeAdapter<Object> rvAdapter;

    private ComboLineColumnChartData chartData;
    private ComboLineColumnChartView chartView;


    private int filterSelected = 0;
    private String filterName;
    private int rvSelected = 0;

    private List<ShiftReport> reports;
    private GroupInfo groupInfo;
    private int groupCnt = 0;
    private int spindleCnt = 0;

    private final static String[] names = new String[]{"产量(kg)", "生产效率(%)", "机械效率(%)", "捻接循环次数", "一次成功捻接次数",
            "接头数", "接头数/10km", "接头数/筒纱", "切疵次数", "切疵/100km",
            "切疵/管纱", "切疵/筒纱", "满筒数", "小车落筒成功数", "换管数", "络纱时间"};
    private final static String[] names_en = new String[]{"Production(kg)", "Pro eff(%)", "Mech eff(%)", "Splices", "Splices of once",
            "Yarn joints", "Yarn joints/10km", "Yarn joints/package", "Cuts", "Cuts/100km",
            "Cuts/cop", "Cuts/package", "Packages", "AD succeed counts", "Cops",
            "Winding time"};
    private static String[] values = new String[]{"50", "90", "94", "53.2", "111",
            "1120", "3", "34", "1000", "103.00",
            "123", "90", "140", "1002", "55",
            "1:32:25"};

    public ProductionSpindleView(Context context) {
        super(context);
        LayoutInflater.from(context).inflate(R.layout.production_general_view, this);
        initViews();
    }

    private void initViews() {
        filterText = findViewById(R.id.filter_text);
        filterBtn = findViewById(R.id.filter_btn);
        filterName = getResources().getString(R.string.all);
        filterText.setText(getResources().getString(R.string.all));
        filterBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                Bundle bundle = new Bundle();
                ArrayList<String> list = new ArrayList<>();
                list.add(getResources().getString(R.string.all));
                list.add(getResources().getString(R.string.average));
                for (int i = 1; i <= groupCnt; ++i) {
                    list.add(getResources().getString(R.string.group) + i);
                }
                for (int i = 1; i <= spindleCnt; ++i) {
                    list.add("" + i);
                }
                bundle.putStringArrayList(CustomSelectedDialog.ITEMS, list);
                CustomSelectedDialog dlg = new CustomSelectedDialog();
                dlg.setArguments(bundle);
                dlg.setCallback(new CustomSelectedDialog.Callback() {
                    @Override
                    public void onItemSelected(String text, int index) {
                        filterName = text;
                        filterText.setText(text);
                        filterSelected = index;
                        updateCraftContent(filterSelected);
                        updateRecycler(filterSelected);
                    }
                });
                dlg.show(((FragmentActivity) getContext()).getSupportFragmentManager(), "selected");
            }
        });
        craftContent = findViewById(R.id.craft_content);
        rv = findViewById(R.id.recycler_view);
        chartView = findViewById(R.id.pie_chart);
        chartView.setInteractive(true);
        chartView.setZoomEnabled(false);
        chartView.setContainerScrollEnabled(true, ContainerScrollType.HORIZONTAL);

        List list = new ArrayList<>();
        String language = Locale.getDefault().getLanguage();
        String[] name = names;
        if (language.equals("en")) {
            name = names_en;
        }
        for (int i = 0; i < name.length; ++i) {
            StatisticButtonAttr attr = new StatisticButtonAttr(name[i], values[i]);
            if (i == 0) {
                attr.setSelected(true);
            }
            list.add(attr);
        }
        rvAdapter = new MultiItemTypeAdapter<Object>(getContext(), list);
        rvAdapter.addItemViewDelegate(new StatisticButtonDelegate(rvAdapter));
        rvAdapter.setOnItemClickListener(new MultiItemTypeAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View view, RecyclerView.ViewHolder holder, int position) {
                if (position == -1)
                    return;
                rvSelected = position;
                for (Object o : rvAdapter.getDatas()) {
                    StatisticButtonAttr attr = (StatisticButtonAttr) o;
                    ((StatisticButtonAttr) o).setSelected(false);
                }
                ((StatisticButtonAttr) rvAdapter.getDatas().get(position)).setSelected(true);
                rvAdapter.notifyDataSetChanged();
                updateChart(rvSelected);

            }

            @Override
            public boolean onItemLongClick(View view, RecyclerView.ViewHolder holder, int position) {
                return false;
            }
        });
        GridLayoutManager layoutManager = new GridLayoutManager(getContext(), 5);
        rv.setLayoutManager(layoutManager);
        rv.addItemDecoration(new SpaceItemDecoration(DensityUtils.dp2px(2), DensityUtils.dp2px(2)));
        rv.setAdapter(rvAdapter);


    }

    public void setData(List<ShiftReport> shiftReports) {
        reports = shiftReports;
        groupInfo = Report.getInstance().getGroupInfo(reports.get(0).start);

        //计算分组数和单锭数
        calcGroupCnt();

        //更新下拉框内容
        updateFilter();

        // 更新recyclerview内容
        updateRecycler(filterSelected);

        // 绘制柱状图
        updateChart(rvSelected);

    }

    public void calcGroupCnt() {
        List<Group> groups = JSON.parseArray(groupInfo.groupInfo, Group.class);
        groupCnt = groups.size();
        int count = 0;
        for (Group group : groups) {
            count += group.getSpindles().size();
        }
        spindleCnt = count;
    }

    public void updateFilter() {
        filterSelected = updateFilterSelected();
        if (filterSelected == 0) {
            filterText.setText(getResources().getString(R.string.all));
        }
        updateCraftContent(filterSelected);
    }

    private int updateFilterSelected() {
        ArrayList<String> list = new ArrayList<>();
        list.add(getResources().getString(R.string.all));
        list.add(getResources().getString(R.string.average));
        for (int i = 1; i <= groupCnt; ++i) {
            list.add(getResources().getString(R.string.group) + i);
        }
        for (int i = 1; i <= spindleCnt; ++i) {
            list.add("" + i);
        }
        int selected = list.indexOf(filterName);
        if (selected == -1) {
            filterName = list.get(0);
            return 0;
        } else {
            return selected;
        }
    }

    private void updateCraftContent(int index) {
        if (groupCnt == 1) {
            Observable.create(new ObservableOnSubscribe<String>() {
                @Override
                public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                    List<SpindleParameter> parameters = JSON.parseArray(groupInfo.spindleParameters, SpindleParameter.class);
                    if (parameters != null && !parameters.isEmpty()) {
                        SpindleParameter parameter = parameters.get(0);
                        StringBuilder sb = new StringBuilder();
                        sb.append("批次:").append("\n").append(parameter.craftName).append("\n");
                        String[] countUnit = getResources().getStringArray(R.array.count_unit);
                        int i = Integer.valueOf(MachineParameterSharedPreference.getInstance().getValue(MachineParameterSharedPreference.SYSTEM_COUNT_UNIT, "0"));
                        sb.append("支数").append("(").append(countUnit[i]).append("):").append("\n").append(String.format("%.1f", UnitUtils.getUICount(Float.parseFloat(parameter.frame28DC)))).append("\n");
                        String spdUnit = getResources().getString(R.string.ss_speedUnit);
                        if (MachineParameterSharedPreference.getInstance().getValue(MachineParameterSharedPreference.SYSTEM_LENGTH_UNIT, "0").equals("1")) {
                            spdUnit = getResources().getString(R.string.behind_ymin);
                        }
                        sb.append("络纱速度").append("(").append(spdUnit).append("):").append("\n").append(UnitUtils.getUILength(parameter.frame20DB));
                        emitter.onNext(sb.toString());
                    } else {
                        emitter.onNext("");
                    }
                }
            })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<String>() {
                        @Override
                        public void accept(String s) throws Exception {
                            craftContent.setText(s);
                        }
                    });

        } else {
            if (index < 2) {
                craftContent.setText("");
            } else {
                Observable.create(new ObservableOnSubscribe<String>() {
                    @Override
                    public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                        List<SpindleParameter> parameters = JSON.parseArray(groupInfo.spindleParameters, SpindleParameter.class);
                        if (parameters != null) {
                            int x = index - 2;
                            int paraIndex = x < groupCnt ? x : GroupMap.getInstance().getSpindleGroupNo(x - groupCnt + 1) - 1;
                            SpindleParameter parameter = parameters.get(paraIndex);
                            StringBuilder sb = new StringBuilder();
                            sb.append("批次:").append("\n").append(parameter.craftName).append("\n");
                            String[] countUnit = getResources().getStringArray(R.array.count_unit);
                            int i = Integer.valueOf(MachineParameterSharedPreference.getInstance().getValue(MachineParameterSharedPreference.SYSTEM_COUNT_UNIT, "0"));
                            sb.append("支数").append("(").append(countUnit[i]).append("):").append("\n").append(String.format("%.1f", UnitUtils.getUICount(Float.parseFloat(parameter.frame28DC)))).append("\n");
                            String spdUnit = getResources().getString(R.string.ss_speedUnit);
                            if (MachineParameterSharedPreference.getInstance().getValue(MachineParameterSharedPreference.SYSTEM_LENGTH_UNIT, "0").equals("1")) {
                                spdUnit = getResources().getString(R.string.behind_ymin);
                            }
                            sb.append("络纱速度").append("(").append(spdUnit).append("):").append("\n").append(UnitUtils.getUILength(parameter.frame20DB));
                            emitter.onNext(sb.toString());
                        } else {
                            emitter.onNext("");
                        }
                    }
                })
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Consumer<String>() {
                            @Override
                            public void accept(String s) throws Exception {
                                craftContent.setText(s);
                            }
                        });
            }

        }

    }

    public void updateRecycler(int index) {
        int i = index;
//        if (index == 0) {
//            i = 0;
//        } else {
//            i = index + 1;
//        }
        ((StatisticButtonAttr) rvAdapter.getDatas().get(0)).setValue(Report.round(String.valueOf(reports.get(i).production), 2));
        ((StatisticButtonAttr) rvAdapter.getDatas().get(1)).setValue(Report.round(String.valueOf(reports.get(i).runEfficiency), 2));
        ((StatisticButtonAttr) rvAdapter.getDatas().get(2)).setValue(Report.round(String.valueOf(reports.get(i).mechanicalEfficiency), 2));
        ((StatisticButtonAttr) rvAdapter.getDatas().get(3)).setValue(String.valueOf(reports.get(i).spliceCount));
        ((StatisticButtonAttr) rvAdapter.getDatas().get(4)).setValue(String.valueOf(reports.get(i).splicesCountRightFirstTime));

        ((StatisticButtonAttr) rvAdapter.getDatas().get(5)).setValue(String.valueOf(reports.get(i).yarnJointCount));
        ((StatisticButtonAttr) rvAdapter.getDatas().get(6)).setValue(Report.round(String.valueOf(reports.get(i).yarnJointCountPer10Km), 2));
        ((StatisticButtonAttr) rvAdapter.getDatas().get(7)).setValue(Report.round(String.valueOf(reports.get(i).yarnJointCountPerPackage), 2));
        ((StatisticButtonAttr) rvAdapter.getDatas().get(8)).setValue(String.valueOf(reports.get(i).cutCount));
        ((StatisticButtonAttr) rvAdapter.getDatas().get(9)).setValue(Report.round(String.valueOf(reports.get(i).cutCountPer10Km), 2));

        ((StatisticButtonAttr) rvAdapter.getDatas().get(10)).setValue(Report.round(String.valueOf(reports.get(i).cutCountPerCop), 2));
        ((StatisticButtonAttr) rvAdapter.getDatas().get(11)).setValue(Report.round(String.valueOf(reports.get(i).cutCountPerPackage), 2));
        ((StatisticButtonAttr) rvAdapter.getDatas().get(12)).setValue(String.valueOf(reports.get(i).packageCount));
        ((StatisticButtonAttr) rvAdapter.getDatas().get(13)).setValue(String.valueOf(reports.get(i).succeedDoffingPackageCount));
        ((StatisticButtonAttr) rvAdapter.getDatas().get(14)).setValue(String.valueOf(reports.get(i).copChangeCount));

        ((StatisticButtonAttr) rvAdapter.getDatas().get(15)).setValue(Report.getInstance().subSecToTime(reports.get(i).windingTime / 1000));

        rvAdapter.notifyDataSetChanged();
    }

    private void updateChart(int index) {
        int numSubcolumns = 1;
        int numColumns = spindleCnt;
        // 坐标设置
        Axis axisX = new Axis();
        Axis axisY = new Axis().setHasLines(true);

        axisY.setFormatter(new SimpleAxisValueFormatter(0));
//        axisX.setName("单锭");
        axisY.setName(names[index]);
        List<AxisValue> axisValues = new ArrayList<>();
        // Column can have many subcolumns, here by default I use 1 subcolumn in each of 8 columns.
        List<Column> columns = new ArrayList<Column>();
        List<Line> lines = new ArrayList<>();
        List<SubcolumnValue> values;
        List<PointValue> pointValues;
        List<Float> shiftData = new ArrayList<>();
        float avgShiftData = 0;
        for (int i = 0; i < numColumns; ++i) {
            switch (index) {
                case 0:
                    shiftData.add(reports.get(i + 2 + groupCnt).production);
                    avgShiftData = reports.get(1).production;
//                    shiftData.add((float) (Math.random()));
                    break;
                case 1:
                    shiftData.add(reports.get(i + 2 + groupCnt).runEfficiency);
                    avgShiftData = reports.get(1).runEfficiency;
                    break;
                case 2:
                    shiftData.add(reports.get(i + 2 + groupCnt).mechanicalEfficiency);
                    avgShiftData = reports.get(1).mechanicalEfficiency;
                    break;
                case 3:
                    shiftData.add((float) reports.get(i + 2 + groupCnt).spliceCount);
                    avgShiftData = reports.get(1).spliceCount;
                    break;
                case 4:
                    shiftData.add((float) reports.get(i + 2 + groupCnt).splicesCountRightFirstTime);
                    avgShiftData = reports.get(1).splicesCountRightFirstTime;
                    break;
                case 5:
                    shiftData.add((float) reports.get(i + 2 + groupCnt).yarnJointCount);
                    avgShiftData = reports.get(1).yarnJointCount;
                    break;
                case 6:
                    shiftData.add(reports.get(i + 2 + groupCnt).yarnJointCountPer10Km);
                    avgShiftData = reports.get(1).yarnJointCountPer10Km;
                    break;
                case 7:
                    shiftData.add(reports.get(i + 2 + groupCnt).yarnJointCountPerPackage);
                    avgShiftData = reports.get(1).yarnJointCountPerPackage;
                    break;
                case 8:
                    shiftData.add((float) reports.get(i + 2 + groupCnt).cutCount);
                    avgShiftData = reports.get(1).cutCount;
                    break;
                case 9:
                    shiftData.add((float) reports.get(i + 2 + groupCnt).cutCountPer10Km);
                    avgShiftData = reports.get(1).cutCountPer10Km;
                    break;
                case 10:
                    shiftData.add((float) reports.get(i + 2 + groupCnt).cutCountPerCop);
                    avgShiftData = reports.get(1).cutCountPerCop;
                    break;
                case 11:
                    shiftData.add((float) reports.get(i + 2 + groupCnt).cutCountPerPackage);
                    avgShiftData = reports.get(1).cutCountPerPackage;
                    break;
                case 12:
                    shiftData.add((float) reports.get(i + 2 + groupCnt).packageCount);
                    avgShiftData = reports.get(1).packageCount;
                    break;
                case 13:
                    shiftData.add((float) reports.get(i + 2 + groupCnt).succeedDoffingPackageCount);
                    avgShiftData = reports.get(1).succeedDoffingPackageCount;
                    break;
                case 14:
                    shiftData.add((float) reports.get(i + 2 + groupCnt).copChangeCount);
                    avgShiftData = reports.get(1).copChangeCount;
                    break;
                case 15:
                    shiftData.add((float) reports.get(i + 2 + groupCnt).windingTime / (60 * 1000));
                    avgShiftData = reports.get(1).windingTime / (60 * 1000);
                    break;

            }
        }

        for (int i = 0; i < numColumns; ++i) {
            values = new ArrayList<SubcolumnValue>();
            for (int j = 0; j < numSubcolumns; ++j) {
                values.add(new SubcolumnValue(shiftData.get(i), Color.rgb(00, 0x53, 0xCD)));
            }
            columns.add(new Column(values));
        }

        pointValues = new ArrayList<>();
        for (int i = 0; i < numColumns; ++i) {
            pointValues.add(new PointValue(i, avgShiftData));
        }
        Line line = new Line(pointValues);
        line.setColor(ChartUtils.COLOR_GREEN);
        line.setHasPoints(false);
        lines.add(line);

        ColumnChartData columnChartData = new ColumnChartData(columns);
        LineChartData lineChartData = new LineChartData(lines);
        chartData = new ComboLineColumnChartData(columnChartData, lineChartData);

        for (int i = 0; i < numColumns; ++i) {
            AxisValue axisValue = new AxisValue(i);
            axisValues.add(axisValue.setLabel(String.valueOf(i + 1)));
        }

        axisX.setValues(axisValues);
        axisX.setLineColor(Color.BLACK);
        axisX.setTextColor(Color.BLACK);
        axisY.setLineColor(Color.BLACK);
        axisY.setTextColor(Color.BLACK);
        chartData.setAxisXBottom(axisX);
        chartData.setAxisYLeft(axisY);
        chartView.setComboLineColumnChartData(chartData);
        chartView.setOnValueTouchListener(new ComboLineColumnChartOnValueSelectListener() {
            @Override
            public void onColumnValueSelected(int columnIndex, int subcolumnIndex, SubcolumnValue value) {
                String columnValue = Report.round(String.valueOf(value.getValue()), 2);
                String spindle = "sp" + (columnIndex + 1);
                GlobalToast.getInstance().show(spindle + " : " + columnValue);
            }

            @Override
            public void onPointValueSelected(int lineIndex, int pointIndex, PointValue value) {

            }

            @Override
            public void onValueDeselected() {

            }
        });
//        Viewport viewport = new Viewport(chartView.getMaximumViewport());
//        viewport.bottom = 0;
//        viewport.top = 400;
//        chartView.setMaximumViewport(viewport);
//        viewport.left = 0;
//        viewport.right = 50;
//        chartView.setCurrentViewport(viewport);

    }

}
